package com.dianban.controller.nengliang;

import com.alibaba.fastjson.JSONObject;
import com.dianban.base.ResultCode;
import com.dianban.base.ResultVo;
import com.dianban.config.redis.RedisConstant;
import com.dianban.config.redis.RedisUtil;
import com.dianban.controller.ApiSyncShoproOrderController;
import com.dianban.controller.BaseController;
import com.dianban.entity.*;
import com.dianban.service.CardService;
import com.dianban.service.FacePayConfigService;
import com.dianban.service.FacePayStoreConsumeLogService;
import com.dianban.service.JwStoreService;
import com.dianban.utils.UserUtils;
import com.dianban.utils.http.HttpClient;
import com.dianban.utils.http.HttpMethod;
import com.dianban.utils.http.HttpParamers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

@Api(value = "ApiCardController", description = "卡号密码控制器")
@RestController
@RequestMapping(value = "${interfacePath}/nengliang/card/")
public class ApiCardController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(ApiCardController.class);
    @Autowired
    private CardService cardService;
    @Autowired
    private FacePayStoreConsumeLogService facePayStoreConsumeLogService;
    @Autowired
    private JwStoreService storeService;
    @Autowired
    private FacePayConfigService facePayConfigService;

    // 提供卡号密码激活逻辑
    @ApiOperation(notes = "activation", httpMethod = "POST", value = "用户激活卡")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userToken", value = "用户token", required = true, paramType = "header", dataType = "string"),
            @ApiImplicitParam(name = "storeId", value = "店铺ID", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "cardNum", value = "卡号", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "activation", method = RequestMethod.POST)
    //@RequestParam(value = "storeId", required = false, defaultValue = "")
    public ResultVo activation(String storeId, String cardNum, String password, HttpServletRequest request, HttpServletResponse response) {
        String userToken = request.getHeader(UserUtils.USER_TOKEN);
        String key = RedisConstant.USER_TOKEN_KEY + userToken;
        User user = (User) RedisUtil.get(key);
        if (user == null) {
            return ResultVo.error(ResultCode.ERROR, "请求头userToken过期");
        }
        try {
            Card card = cardService.findByCardNum(cardNum);
            if (card == null) {
                return ResultVo.error(ResultCode.ERROR, "不存在该卡号或卡号已激活");
            }
            if ("1".equals(card.getStatus())) {
                return ResultVo.error(ResultCode.ERROR, "卡号已被激活，无法再激活");
            }
            Date now = new Date();
            if (now.compareTo(card.getEffectiveTimeStart()) >= 0 && now.compareTo(card.getEffectiveTimeEnd()) <= 0) {
                // 有效期内
            } else {
                return ResultVo.error(ResultCode.ERROR, "卡号不在有效的激活时间范围内");
            }
            if (!password.equals(card.getPassword())) {
                return ResultVo.error(ResultCode.ERROR, "密码不对无法激活");
            }
            if (StringUtils.isNotBlank(storeId)) {
                card.setStoreId(storeId);
            }
            card.setStatus("1");
            card.setUserId(user.getId());
            card.setActivationTime(now);
            cardService.update(card.getId(), card.getStatus(), card.getUserId(), card.getActivationTime(), storeId);
        } catch (Throwable e) {
            e.printStackTrace();
            return ResultVo.error(ResultCode.ERROR, "激活失败");
        }
        Map<String, Object> resultMap = new HashMap<>();
        return ResultVo.success(resultMap, "激活成功");
    }

    @ApiOperation(notes = "list", httpMethod = "GET", value = "获取拥有的卡")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userToken", value = "用户token", required = true, paramType = "header", dataType = "string"),
            @ApiImplicitParam(name = "storeId", value = "店铺ID", required = false, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "list", method = RequestMethod.GET)
    public ResultVo mycard(@RequestParam(value = "storeId", required = false, defaultValue = "") String storeId, HttpServletRequest request, HttpServletResponse response) {
        String userToken = request.getHeader(UserUtils.USER_TOKEN);
        String key = RedisConstant.USER_TOKEN_KEY + userToken;
        User user = (User) RedisUtil.get(key);
        if (user == null) {
            return ResultVo.error(ResultCode.ERROR, "请求头userToken过期");
        }
        List<Card> cardList = new ArrayList<>();
        try {
            Set<Long> storeIds = new HashSet<>();
            List<Long> storeIdList = new ArrayList<>();
            cardList = cardService.findList(user.getId(), storeId);
            if (!CollectionUtils.isEmpty(cardList)) {
                for (Card card : cardList) {
                    storeIds.add(Long.valueOf(card.getStoreId()));
                }
                if (!CollectionUtils.isEmpty(storeIds)) {
                    storeIdList.addAll(storeIds);
                }
            }
            // 门店名称查询出来
            List<JwStore> storeList = storeService.findList("");
            Map<String, String> storeStatusMap = new HashMap<>();
            Map<Long, String> storeMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(storeList)) {
                for (JwStore jwStore : storeList) {
                    storeMap.put(jwStore.getId(), jwStore.getName());
                }
                for (JwStore jwStore : storeList) {
                    if (!storeIdList.contains(jwStore.getId())) {
                        continue;
                    }
                    if (StringUtils.isEmpty(storeStatusMap.get(storeMap.get(jwStore.getId())))) {
                        String onlineStatus = "0";
                        // 查询门店设备在线状态
                        List<FacePayConfig> facePayConfigList = facePayConfigService.find(20, null, jwStore.getId());
                        if (!facePayConfigList.isEmpty()) {
                            // sn号,查询设备是否在线
                            String name = facePayConfigList.get(0).getName();
                            String url = "http://120.24.76.21:8080/iot-admin/app/modbus/equipStatusCheck?sn=" + name;
                            HttpParamers httpParamers = new HttpParamers(HttpMethod.GET);
                            String resultService = HttpClient.doService(url, httpParamers, null);
                            if (StringUtils.isNotBlank(resultService)) {
                                JSONObject jsonObject = JSONObject.parseObject(resultService);
                                if (jsonObject != null && jsonObject.get("code") != null
                                        && "0".equals(String.valueOf(jsonObject.get("code")))) {
                                    onlineStatus = String.valueOf(jsonObject.get("onlineStatus"));
                                }
                            }
                        }
                        storeStatusMap.put(storeMap.get(jwStore.getId()), onlineStatus);
                    }
                }
            }
            if (!CollectionUtils.isEmpty(cardList)) {
                for (Card card : cardList) {
                    card.setStoreName(storeMap.get(Long.valueOf(card.getStoreId())));
                    card.setStoreIsOnline(storeStatusMap.get(storeMap.get(Long.valueOf(card.getStoreId()))));
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            return ResultVo.error(ResultCode.ERROR, "获取失败");
        }
        return ResultVo.success(cardList, "获取成功");
    }

    @ApiOperation(notes = "info", httpMethod = "GET", value = "卡号详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userToken", value = "用户token", required = true, paramType = "header", dataType = "string"),
            @ApiImplicitParam(name = "cardNum", value = "卡号", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "info", method = RequestMethod.GET)
    public ResultVo info(String cardNum, HttpServletRequest request, HttpServletResponse response) {
        String userToken = request.getHeader(UserUtils.USER_TOKEN);
        String key = RedisConstant.USER_TOKEN_KEY + userToken;
        User user = (User) RedisUtil.get(key);
        if (user == null) {
            return ResultVo.error(ResultCode.ERROR, "请求头userToken过期");
        }
        Card card = null;
        try {
            card = cardService.findByCardNum(cardNum);
            if (card == null) {
                return ResultVo.error(ResultCode.ERROR, "不存在该卡号");
            }
        } catch (Throwable e) {
            e.printStackTrace();
            return ResultVo.error(ResultCode.ERROR, "获取失败");
        }
        return ResultVo.success(card, "获取成功");
    }

    @ApiOperation(notes = "verify", httpMethod = "GET", value = "卡号在门店体验能量舱核销")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userToken", value = "用户token", required = true, paramType = "header", dataType = "string"),
            @ApiImplicitParam(name = "cardNum", value = "卡号", required = true, paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "storeId", value = "门店id", required = true, paramType = "query", dataType = "string"),
    })
    @RequestMapping(value = "verify", method = RequestMethod.GET)
    public ResultVo verify(String cardNum, String storeId, HttpServletRequest request, HttpServletResponse response) {
        logger.info("卡号在门店体验能量舱核销 cardNum-{}, storeId-{}", cardNum, storeId);
        JSONObject jsonObject = JSONObject.parseObject(storeId);
        if (jsonObject != null) {
            storeId = String.valueOf(jsonObject.get("storeId"));
            cardNum = String.valueOf(jsonObject.get("cardNum"));
        }
        String userToken = request.getHeader(UserUtils.USER_TOKEN);
        String key = RedisConstant.USER_TOKEN_KEY + userToken;
        User user = (User) RedisUtil.get(key);
        if (user == null) {
            return ResultVo.error(ResultCode.ERROR, "请求头userToken过期");
        }
        Long userId = user.getId();
        try {
            Card card = cardService.findByCardNum(cardNum);
            if (card == null) {
                return ResultVo.error(ResultCode.ERROR, "不存在该卡号");
            }
            if (!storeId.equals(card.getStoreId())) {
                return ResultVo.error(ResultCode.ERROR, "不是在当前门店激活的无法在本门店使用");
            }
            if ("0".equals(card.getStatus())) {
                return ResultVo.error(ResultCode.ERROR, "卡号尚未激活，请先激活");
            }
            if (!card.getUserId().equals(user.getId())) {
                return ResultVo.error(ResultCode.ERROR, "此卡号关联人不是您，无法操作");
            }
            Integer count = card.getCanVerify() - card.getHasVerify();
            if (count <= 0) {
                return ResultVo.error(ResultCode.ERROR, "可核销次数不足，无法使用");
            }
            // 记录消费次数，更新卡号核销次数，远程控制打开开关
            FacePayStoreConsumeLog facePayStoreConsumeLog = new FacePayStoreConsumeLog();
            facePayStoreConsumeLog.setStoreId(Long.parseLong(storeId));
            facePayStoreConsumeLog.setUserId(userId);
            facePayStoreConsumeLog.setMoney(BigDecimal.ZERO);
            facePayStoreConsumeLog.setType("50");
            facePayStoreConsumeLog.setCardId(card.getId());
            facePayStoreConsumeLog.setMemo("卡号核销");
            return facePayStoreConsumeLogService.verifyCard(facePayStoreConsumeLog);
        } catch (Throwable e) {
            e.printStackTrace();
            return ResultVo.error(ResultCode.ERROR, "操作失败");
        }
    }
}
